package com.example.experiment4;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;

public class Calculate {

    private LocalDateTime start_time;
    private LocalDateTime end_time;

    public Calculate(String start_time, String end_time) {
//        规定输入格式
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        this.start_time = LocalDateTime.parse(start_time, df);
        this.end_time = LocalDateTime.parse(end_time, df);
    }

    //    假定每年3月第二个星期天凌晨2点开始夏令时，每年11月第一个星期天凌晨2点夏令时结束
    public double calculateFree() {
//        获取日期
//        LocalDate start_date = start_time.toLocalDate();
//        LocalDate end_date = end_time.toLocalDate();

//        开始时间和结束时间都不处于夏令时阶段
        if (!isDaylightSavingTime(start_time) && !isDaylightSavingTime((end_time))) {
//            计算时间差值
            Duration duration = Duration.between(start_time, end_time);
            long minute = duration.toMinutes();
            long millis = duration.toMillis();
            if (millis / 1000 > minute * 60) minute++;
//            如果时间差值小于0，说明开始时间和结束时间错误
            if (millis < 0) return -1;
//            如果时间大于30h，说明开始时间和结束时间错误
            if (duration.toHours() > 30) return -1;
//            计算费用
            return calculateFree(minute);
        }
//        开始时间不处于夏令时阶段，结束时间处于夏令时阶段
        else if (!isDaylightSavingTime(start_time) && isDaylightSavingTime(end_time)) {
//            计算时间差值
            Duration duration = Duration.between(start_time, end_time);
            long minute = duration.toMinutes();
            if (duration.toMillis() / 1000 > minute * 60) minute++;
//            由于夏令时的缘故，在原有通话时间的基础上减去一小时
            minute -= Duration.ofHours(1).toMinutes();
//            如果时间大于30h，说明开始时间和结束时间错误
            if (duration.toHours() > 30) return -1;
//            计算费用
            return calculateFree(minute);
        }
//        开始时间和结束时间都处于夏令时阶段
        else if (isDaylightSavingTime(start_time) && isDaylightSavingTime(end_time)) {
//            计算时间差值
            Duration duration = Duration.between(start_time, end_time);
            long minute = duration.toMinutes();
            long millis = duration.toMillis();
//            判断是不是因为夏令时导致的时间差小于0
            if (millis < 0 && (start_time.toLocalDate().get(ChronoField.MONTH_OF_YEAR) != 3 && end_time.toLocalDate().get(ChronoField.MONTH_OF_YEAR) != 11)) {
                return -1;
            }
//            判断是否因为夏令时缘故导致结束时间在被判断为处于夏令时阶段
            if (millis <= 0) {
//                表示结束时间已经不在夏令时阶段
//            由于夏令时的缘故，在原有通话时间的基础上加上一小时
                minute += Duration.ofHours(1).toMinutes();
                millis += Duration.ofHours(1).toMillis();
                if (millis / 1000 > minute * 60) minute++;
            }
//            如果时间大于30h，说明开始时间和结束时间错误
            if (duration.toHours() > 30) return -1;
//            计算费用
            if (millis / 1000 > minute * 60) minute++;
            return calculateFree(minute);
        }
//        开始时间处于夏令时阶段，结束时间不处于夏令时阶段
        else if (isDaylightSavingTime(start_time) && !isDaylightSavingTime(end_time)) {
//            计算时间差值
            Duration duration = Duration.between(start_time, end_time);
            long minute = duration.toMinutes();
            if (duration.toMillis() / 1000 > minute * 60) minute++;
//            由于夏令时的缘故，在原有通话时间的基础上加上一小时
            minute += Duration.ofHours(1).toMinutes();
//            如果时间大于30h，说明开始时间和结束时间错误
            if (duration.toHours() > 30) return -1;
//            计算费用
            return calculateFree(minute);
        }
        else return -1;
    }

    public double calculateFree (long minute) {
        if (minute <= 20) {
            BigDecimal bg = new BigDecimal(minute * 0.05);
            return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        } else {
            BigDecimal bg = new BigDecimal(1 + (minute - 20) * 0.1);
            return bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
    }

    boolean isDaylightSavingTime(LocalDateTime time) {
        LocalDate localDate = time.toLocalDate();
        LocalTime localTime = time.toLocalTime();
//        获取月
        int month = localDate.get(ChronoField.MONTH_OF_YEAR);
//        获取日
        int day = localDate.get(ChronoField.DAY_OF_MONTH);
//        获取小时
        int hour = localTime.getHour();

        if (month > 3 && month < 11) return true;
//        判断是否是3月的第二个星期天之后或者11的第一个星期天之前
        else return (month == 3 && day >= 8 && day <= 13 && hour >= 2) || (month == 11 && day >= 1 && day <= 7 && hour <= 2);
    }

}
